home *** CD-ROM | disk | FTP | other *** search
- /*
- * Title:
- * database.c
- *
- * Authors:
- * Michael P. Schenck
- *
- * Purpose:
- * Maintains the storage of all the models and objects used in the
- * renderer. Models can be requested. Objects although are not
- * used by the main program directly. They are allocated when a node
- * in the displaymap is created which has a model linked to it. Models
- * are the schematics of the objects. Multiple objects can use the same
- * model for thier design and this can allow the model to be changed
- * (only position of verticies) to create animation or to morph one
- * model to another. Models can be released, but do not need to
- * be. When the system is closed, all models will be released anyway.
- * When a model is requested, an id is returned specific to the model.
- * If a model could not be setup, a NOMODEL value is returned.
- *
- * Copyright Info:
- * Copyright (C) 1993, 1994 -- by Michael P. Schenck,
- * (mps4466@ultb.isc.rit.edu)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License,
- * or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * For a copy of the GNU General Public License
- * write to the Free Software Foundation, 675 Mass Ave,
- * Cambridge, MA 02139, USA.
- *
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "/include/types.h"
- #include "/include/errors.h"
- #include "/include/displaymap.h"
- #include "/include/matrix.h"
- #include "/include/database.h"
-
- struct Model *models[MAXNUMMODELS+1];
- struct Object *objects[MAXNUMOBJECTS+1];
-
- static UBYTE *linemap = NULL;
- static ULONG curlmsize = 0;
- static UBYTE modelpath[MAXPATHLEN];
- static UBYTE temp[MAXPATHLEN+MAXNAMELEN];
- static FILE *fp;
-
- ULONG findemptymodelnode(void);
- ULONG findmodel(UBYTE *);
- ULONG findemptyobjectnode(void);
-
- /* Open the database and set the path to the models. */
-
- void opendatabase(UBYTE *path)
-
- {
- cleardisplaymap();
- setdatabasepath(path);
- }
-
- void setdatabasepath(UBYTE *path)
-
- {
- strcpy(modelpath,path);
- }
-
- /* Find an empty model node in the list. */
-
- ULONG findemptymodelnode()
-
- {
- ULONG i;
-
- for(i=0;i<MAXNUMMODELS;i++) {
- if(models[i]==NULL)
- return(i);
- }
- return(NOMODEL);
- }
-
- /* Looks to see if a model has already been loaded into the database. */
-
- ULONG findmodel(UBYTE *name)
-
- {
- ULONG i;
-
- for(i=0;i<MAXNUMMODELS;i++) {
- if((models[i]!=NULL)&&(stricmp(models[i]->name,name)==0)&&(models[i]->links!=0))
- return(i);
- }
- return(NOMODEL);
- }
-
- /* Requests a model to be loaded into the database. */
-
- ULONG requestmodel(UBYTE *name, UBYTE type)
-
- {
- ULONG position,numlinks,numvert,numpoly,j,k,offset,firstvert,curvert,nextvert;
- UBYTE *linemaptmp;
-
-
- if(type==SINGLELINK) {
- position=findemptymodelnode();
- numlinks=0;
- }
- else {
- if((position=findmodel(name))!=NOMODEL) {
- models[position]->links++;
- numlinks=models[position]->links;
- }
- else {
- position=findemptymodelnode();
- numlinks=1;
- }
- }
- if((position!=NOMODEL)&&(numlinks<2)) {
- strcpy(temp,modelpath);
- if((fp=fopen(strcat(temp,name),"r"))!=NULL) {
- fread((void *)&numvert,sizeof(ULONG),1,fp);
- fread((void *)&numpoly,sizeof(ULONG),1,fp);
- if((models[position]=(struct Model *)malloc(sizeof(struct Model)))==NULL) {
- fclose(fp);
- models[position]=NULL;
- return(NOMODEL);
- }
- if((models[position]->verticies=(FLOAT *)malloc(4*numvert*sizeof(FLOAT)))==NULL) {
- fclose(fp);
- free((void *)models[position]);
- models[position]=NULL;
- return(NOMODEL);
- }
- if((models[position]->polygons=(ULONG *)malloc(numpoly*MAXPOLYVERT*sizeof(ULONG)))==NULL) {
- fclose(fp);
- free((void *)models[position]->verticies);
- free((void *)models[position]);
- models[position]=NULL;
- return(NOMODEL);
- }
- models[position]->links=numlinks;
- models[position]->numvert=numvert;
- models[position]->numpoly=numpoly;
- strcpy(models[position]->name,name);
- fread((void *)models[position]->verticies,sizeof(FLOAT),4*numvert,fp);
- fread((void *)models[position]->polygons,sizeof(ULONG),numpoly*MAXPOLYVERT,fp);
- fclose(fp);
- if(numvert > curlmsize) {
- if((linemaptmp = (UBYTE *)realloc((void *)linemap,numvert*numvert*sizeof(UBYTE))) == NULL) {
- free((void *)models[position]->polygons);
- free((void *)models[position]->verticies);
- free((void *)models[position]);
- models[position]=NULL;
- return(NOMODEL);
- }
- linemap = linemaptmp;
- curlmsize = numvert;
- }
-
- for(j=0;j<curlmsize*curlmsize;j++)
- *(linemap+j) = FALSE;
-
- if((models[position]->edgeshare=(UBYTE *)malloc(numpoly*MAXPOLYVERT*sizeof(UBYTE)))==NULL) {
- free((void *)models[position]->polygons);
- free((void *)models[position]->verticies);
- free((void *)models[position]);
- models[position]=NULL;
- return(NOMODEL);
- }
-
- for(j=0;j<numpoly*MAXPOLYVERT;j++)
- *(models[position]->edgeshare+j) = TRUE;
-
- for(j=0;j<numpoly*MAXPOLYVERT;j+=MAXPOLYVERT) {
- firstvert = *(models[position]->polygons+j);
- curvert = firstvert;
- for(k=1;k<(MAXPOLYVERT-1);k++) {
- offset = k;
- if((nextvert = *(models[position]->polygons+j+k))==NOVERT) {
- k=MAXPOLYVERT-1;
- nextvert = firstvert;
- }
- if(*(linemap+curvert*curlmsize+nextvert) == FALSE) {
- *(linemap+curvert*curlmsize+nextvert) = TRUE;
- *(linemap+nextvert*curlmsize+curvert) = TRUE;
- }
- else
- *(models[position]->edgeshare+j+offset-1) = FALSE;
- curvert = nextvert;
- }
- }
- }
- else
- position=NOMODEL;
- }
- return(position);
- }
-
- /* Releases the model specified. If there is more than one link,
- it decrements the link by one. */
-
- void releasemodel(ULONG model)
-
- {
- if(models[model]->links>1)
- models[model]->links--;
- else {
- free((void *)models[model]->edgeshare);
- free((void *)models[model]->verticies);
- free((void *)models[model]->polygons);
- free((void *)models[model]);
- models[model]=NULL;
- }
- }
-
- /* Finds an available object node. */
-
- ULONG findemptyobjectnode()
-
- {
- ULONG i;
-
- for(i=0;i<MAXNUMOBJECTS;i++) {
- if(objects[i]==NULL)
- return(i);
- }
- return(NOOBJECT);
- }
-
- /* Allocates space for an object and links to an object node. */
-
- ULONG allocateobject(ULONG model)
-
- {
- ULONG i,position;
-
- if((position=findemptyobjectnode())==NOOBJECT)
- return(NOOBJECT);
- if((objects[position]=(struct Object *)malloc(sizeof(struct Object)))==NULL)
- return(NOOBJECT);
- if((objects[position]->verticies=(FLOAT *)malloc(4*models[model]->numvert*sizeof(FLOAT)))==NULL) {
- free((void *)objects[position]);
- objects[position]=NULL;
- return(NOOBJECT);
- }
- if((objects[position]->transvert=(FLOAT *)malloc(4*models[model]->numvert*sizeof(FLOAT)))==NULL) {
- free((void *)objects[position]->verticies);
- free((void *)objects[position]);
- objects[position]=NULL;
- return(NOOBJECT);
- }
- if((objects[position]->vertflag=(UBYTE *)malloc(models[model]->numvert*sizeof(UBYTE)))==NULL) {
- free((void *)objects[position]->verticies);
- free((void *)objects[position]->transvert);
- free((void *)objects[position]);
- objects[position]=NULL;
- return(NOOBJECT);
- }
- if((objects[position]->polygons=(ULONG *)malloc(models[model]->numpoly*MAXPOLYVERT*sizeof(ULONG)))==NULL) {
- free((void *)objects[position]->verticies);
- free((void *)objects[position]->transvert);
- free((void *)objects[position]->vertflag);
- free((void *)objects[position]);
- objects[position]=NULL;
- return(NOOBJECT);
- }
- for(i=0;i<models[model]->numpoly*MAXPOLYVERT;i++)
- *(objects[position]->polygons+i) = *(models[model]->polygons+i);
- objects[position]->numvert = models[model]->numvert;
- objects[position]->numpoly = models[model]->numpoly;
- objects[position]->edgeshare = models[model]->edgeshare;
- return(position);
- }
-
- /* Deallocates an object. */
-
- void deallocateobject(ULONG object)
-
- {
- free((void *)objects[object]->verticies);
- free((void *)objects[object]->transvert);
- free((void *)objects[object]->vertflag);
- free((void *)objects[object]->polygons);
- free((void *)objects[object]);
- objects[object]=NULL;
- }
-
- /* Closes down the database, releasing all models and objects. */
-
- void closedatabase()
-
- {
- ULONG i;
-
- cleardisplaymap();
- for(i=0;i<MAXNUMMODELS;i++) {
- if(models[i]!=NULL)
- releasemodel(i);
- }
- for(i=0;i<MAXNUMOBJECTS;i++) {
- if(objects[i]!=NULL)
- deallocateobject(i);
- }
- if(linemap)
- free((void *)linemap);
- }
-